package com.nlecloud.bc.service.contract.impl;

import com.nlecloud.bc.constant.CustomerConstant;
import com.nlecloud.bc.contract.Copyright;
import com.nlecloud.bc.controller.contract.dto.CopyrightDTO;
import com.nlecloud.bc.interceptor.AuthTokenStorage;
import com.nlecloud.bc.model.PageResult;
import com.nlecloud.bc.model.User;
import com.nlecloud.bc.service.contract.ICopyrightContractService;
import com.nlecloud.bc.service.contract.IUserContractService;
import com.nlecloud.bc.util.FileUtil;
import com.nlecloud.bc.util.MD5Util;
import lombok.extern.slf4j.Slf4j;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple6;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.model.TransactionReceipt;
import org.fisco.bcos.sdk.transaction.model.exception.ContractException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @author warrior
 * @description 版权合约操作服务接口实现
 */
@Service
@Slf4j
public class CopyrightContractService implements ICopyrightContractService {

    private static final String FILE_SPLIT = "/";

    private static final String FILE_DOT = ".";

    @Value("${fisco.bcos.contract.copyright.address}")
    private String contractCopyrightAddress;

    @Value("${file-save-path}")
    private String fileSavePath;

    @Autowired
    private Client client;

    @Autowired
    private IUserContractService contractUserService;

    @Override
    public boolean addCopyright(String title, String path,String author) throws IOException {
        String uuid = path.substring(path.lastIndexOf(FILE_SPLIT) + 1, path.lastIndexOf(FILE_DOT));
        User user = AuthTokenStorage.getUser();
        String ownerId = user.getId();
        String hash = MD5Util.getUrlFileMd5(path);
        Copyright copyright = Copyright.load(contractCopyrightAddress, client, client.getCryptoSuite().getCryptoKeyPair());
        TransactionReceipt transactionReceipt = copyright.insertCopyright(uuid, title, hash, ownerId, author);
        log.info("add copyright traction receipt {}", transactionReceipt.toString());
        String status = transactionReceipt.getStatus();
        return CustomerConstant.SUCCESS_STATUS.equals(status);
    }

    @Override
    public PageResult<CopyrightDTO> listCopyrightByOwnerId(String userId, int index, int size, HttpServletRequest req) throws ContractException {
        Copyright copyright = Copyright.load(contractCopyrightAddress, client, client.getCryptoSuite().getCryptoKeyPair());
        Tuple6<BigInteger, List<String>, List<String>, List<BigInteger>, List<String>, List<BigInteger>> tuple6 = copyright.selectCopyrightByOwnerid(userId, new BigInteger(String.valueOf(index)), new BigInteger(String.valueOf(size)));

        long total = tuple6.getValue1().longValue();
        List<String> uuids = tuple6.getValue2();
        List<String> titles = tuple6.getValue3();
        List<BigInteger> statuss = tuple6.getValue4();
        List<String> authors = tuple6.getValue5();
        List<BigInteger> times = tuple6.getValue6();

        if(total == 0){
            return PageResult.emptyPageResult(size, index);
        }

        List<CopyrightDTO> copyrightDTOS = new ArrayList<>(uuids.size());
        for (int i = 0; i < uuids.size(); i++) {
            CopyrightDTO copyrightDTO = new CopyrightDTO();
            copyrightDTO.setUuid(uuids.get(i));
            copyrightDTO.setTitle(titles.get(i));
            copyrightDTO.setStatus(statuss.get(i));
            copyrightDTO.setAuthor(authors.get(i));
            copyrightDTO.setTime(times.get(i));
            String fileName = FileUtil.searchFile(fileSavePath, uuids.get(i));
            String path = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + "/uploadFile/" + fileName;
            copyrightDTO.setPath(path);
            copyrightDTOS.add(copyrightDTO);
        }
        return PageResult.pagination(size, index, total, copyrightDTOS);
    }

    @Override
    public PageResult<CopyrightDTO> listCopyrightByStatus(int status, int index, int size, HttpServletRequest req) throws ContractException {
        Copyright copyright = Copyright.load(contractCopyrightAddress, client, client.getCryptoSuite().getCryptoKeyPair());
        Tuple6<BigInteger, List<String>, List<String>, List<BigInteger>, List<String>, List<BigInteger>> tuple6 = copyright.selectCopyrightByStatus(new BigInteger(String.valueOf(status)), new BigInteger(String.valueOf(index)), new BigInteger(String.valueOf(size)));

        long total = tuple6.getValue1().longValue();
        List<String> uuids = tuple6.getValue2();
        List<String> titles = tuple6.getValue3();
        List<BigInteger> amounts = tuple6.getValue4();
        List<String> authors = tuple6.getValue5();
        List<BigInteger> times = tuple6.getValue6();

        if(total == 0){
            return PageResult.emptyPageResult(size, index);
        }

        List<CopyrightDTO> copyrightDTOS = new ArrayList<>(uuids.size());
        for (int i = 0; i < uuids.size(); i++) {
            CopyrightDTO copyrightDTO = new CopyrightDTO();
            copyrightDTO.setUuid(uuids.get(i));
            copyrightDTO.setTitle(titles.get(i));
            copyrightDTO.setAmount(amounts.get(i));
            copyrightDTO.setAuthor(authors.get(i));
            copyrightDTO.setTime(times.get(i));
            String fileName = FileUtil.searchFile(fileSavePath, uuids.get(i));
            String path = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + "/uploadFile/" + fileName;
            copyrightDTO.setPath(path);
            copyrightDTOS.add(copyrightDTO);
        }
        return PageResult.pagination(size, index, total, copyrightDTOS);
    }

    @Override
    public boolean setStatusAndAmount(String uuid, int status, BigInteger amount) {
        Copyright copyright = Copyright.load(contractCopyrightAddress, client, client.getCryptoSuite().getCryptoKeyPair());
        TransactionReceipt transactionReceipt = copyright.setStatusAndAmount(uuid,BigInteger.valueOf(status), amount);
        log.info("set status and amount traction receipt {}", transactionReceipt.toString());
        String result = transactionReceipt.getStatus();
        return CustomerConstant.SUCCESS_STATUS.equals(result);
    }
}
